L'objectif de ce test est à partir des données fournies, l'identifiant du magasin , identifiant de l'appareil, date du ping, d'inferer les horaires d'ouverture des magasins.
Je cherche dans cet exercice à mettre en avant une méthode automatique viable pour n'importe quel magasin dans n'importe quelle situation à déterminer à partir des données disponible ses horaires d'ouverture.
Une premiere approche pourrait etre d'estimer par jour la distribution des pings au cours de la journée et définir un seuil d'acceptation cependant il est d'une part difficile de trouver automatiquement ce seuil d'acceptation pour chaque magasin et rien ne dit que choisir un seuil basé sur nos données se généralisera bien à d'autres magasins.
La méthode choisie est alors la suivante, je suppose que les arrivées des clients à chaque instant suivent une loi de poisson de paramètre inconnu. Ce parametre suit une loi continue en fonction du temps et dépend d'un paramètre correspondant à l'ouverture ou non du magasin, je vais donc chercher à detecter l'instant ou le paramètre change de loi c'est à dire "saut" dans les fréquences d'arrivées.
Pour ce faire je vais chercher deux instants t1 et t2 tel et calculer le MSE entre les observations o(t) et la fonction définie par f(t) =
mean(o(t) pour t < t1) si t < t1 | mean(o(t) pour t > t2) si t > t2 | mean(o(t) pour t > t1 et t< t2) t > t1 et t< t2 |
je fais referece à cette méthode par la "méthode des moyennes"
Tous les graphiques utilisent altair et sont interactif vous pouvez zoomer en "scrollant" déplacer le graphique en cliquant et tirant et vous pouvez selectionner le centre commercial en cliquant sur la légende.
Pour plus de confort j'ai "collapsé" les cellules les moins importantes j'utilise vs code j'espere que l'affichage sera bon de votre coté
PS: j'ai supprimé mes différents essais intermédiaires pour ne garder que l'essais final avec tout le preprocessing ect...
import pandas as pd
import altair as alt
import datetime
import numpy as np
import scipy.stats as stats
alt.data_transformers.disable_max_rows()
DataTransformerRegistry.enable('default')
Visualisation des informations importantes
data = pd.read_csv("./at_home_test_data_study_centers_201909.csv")
data.info()
data.head()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 81838 entries, 0 to 81837 Data columns (total 3 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 shopping_center_id 81838 non-null object 1 device_local_date 81838 non-null object 2 device_hash_id 81838 non-null object dtypes: object(3) memory usage: 1.9+ MB
| shopping_center_id | device_local_date | device_hash_id | |
|---|---|---|---|
| 0 | b43e9e4f-acd1-4941-874d-e0c5650ab91e | 2019-09-14 10:00:25 | 6fdffac307 |
| 1 | b43e9e4f-acd1-4941-874d-e0c5650ab91e | 2019-09-14 17:13:15 | 386141ebd8 |
| 2 | b43e9e4f-acd1-4941-874d-e0c5650ab91e | 2019-09-14 9:07:06 | b06242b848 |
| 3 | b43e9e4f-acd1-4941-874d-e0c5650ab91e | 2019-09-14 17:14:49 | c13cc52e82 |
| 4 | 599cb959-11ef-49aa-9eb3-e6c17b4ea6ba | 2019-09-14 10:17:35 | f339ddf999 |
min_date_serie = data[['shopping_center_id','device_local_date']].groupby("shopping_center_id").apply(lambda x: x['device_local_date'].min()).rename("min_date")
max_date_serie = data[['shopping_center_id','device_local_date']].groupby("shopping_center_id").apply(lambda x: x['device_local_date'].max()).rename("max_date")
pd.concat([min_date_serie,max_date_serie],axis=1)
| min_date | max_date | |
|---|---|---|
| shopping_center_id | ||
| 0cd35523-1eca-4f09-ab0d-0b506ae9d986 | 2019-09-01 16:18:00 | 2019-09-17 9:59:00 |
| 599cb959-11ef-49aa-9eb3-e6c17b4ea6ba | 2019-09-01 0:19:53 | 2019-09-17 9:59:42 |
| b43e9e4f-acd1-4941-874d-e0c5650ab91e | 2019-09-01 10:03:09 | 2019-09-17 9:57:59 |
| cb2d5bb6-c372-4a51-8231-4ffa288a0c28 | 2019-09-01 0:26:16 | 2019-09-17 9:59:55 |
data[['shopping_center_id','device_hash_id']].groupby('shopping_center_id').nunique()
| device_hash_id | |
|---|---|
| shopping_center_id | |
| 0cd35523-1eca-4f09-ab0d-0b506ae9d986 | 1077 |
| 599cb959-11ef-49aa-9eb3-e6c17b4ea6ba | 2417 |
| b43e9e4f-acd1-4941-874d-e0c5650ab91e | 1024 |
| cb2d5bb6-c372-4a51-8231-4ffa288a0c28 | 1334 |
selection = alt.selection_multi(fields=['shopping_center_id'], bind='legend')
chart = alt.Chart(data).encode(
alt.X('yearmonthdatehoursminutes(device_local_date):T'),
alt.Y('distinct(device_hash_id):Q',stack=None),
color='shopping_center_id:N',
opacity=alt.condition(selection, alt.value(1), alt.value(0))
).add_selection(selection)
chart.mark_bar(opacity=1, thickness=100,size=2).interactive()